/**
 * @filename:PurInServiceImpl Jan 15, 2025
 * @project Wonder Vue Admin Api  1.1.0
 * Copyright(c) 2022 Wonder Co. Ltd. 
 * All right reserved. 
 */
package com.wonder.app.service.impl;

import cn.hutool.core.date.DateTime;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.admin.domain.SysAdmin;
import com.wonder.admin.service.IVtuzxKingdeeService;
import com.wonder.admin.service.SysAdminService;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.MaterialDao;
import com.wonder.app.mapper.PurInDao;
import com.wonder.app.mapper.PurInDetailDao;
import com.wonder.app.mapper.ReceiveDao;
import com.wonder.app.service.PurInDetailService;
import com.wonder.app.service.PurInService;
import com.wonder.app.request.PurInRequest;
import com.wonder.app.service.SyncKingdeeOrderService;
import com.wonder.app.service.YzjService;
import com.wonder.bean.kingdee.VtuzxKingdeeCloudClient;
import com.wonder.bean.kingdee.xqc.VtuzxArrayList;
import com.wonder.common.utils.StringUtils;
import com.wonder.common.utils.MessageUtils;
import com.wonder.common.common.AjaxResult;

import java.util.*;

import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

/**   
 * @Description:TODO(采购入库单列表服务实现)
 *
 * @version: 1.1.0
 * @author: Wonder
 * 
 */
@Service
public class PurInServiceImpl  extends ServiceImpl<PurInDao, PurIn> implements PurInService  {
	/**
	 * Logger
	 */
	private static final Logger _logger = LoggerFactory.getLogger(PurInServiceImpl.class);

	@Autowired
	private PurInService purInService;

	@Autowired
	private IVtuzxKingdeeService vtuzxKingdeeService;

	@Autowired
	private SysAdminService adminService;

	@Autowired
	private YzjService yzjService;

	@Autowired
	private PurInDetailService purInDetailService;
	@Autowired
	private PurInDao purInDao;
	@Autowired
	private PurInDetailDao purInDetailDao;

	@Autowired
	private MaterialDao materialDao;


	@Autowired
	private ReceiveDao receiveDao;

	@Autowired
	private SyncKingdeeOrderService syncKingdeeOrderService;
    /**
     * 验证采购入库单列表信息
     * 
     * @param purIn
     * @param type
     * @return String
     */
    @Override
    public String validate(PurIn purIn,String type){
    
    
       return "";
    }
    
    
    /**
	 * Description:采购入库单列表分页返回
	 * @param request //检索条件
	 * @param page //分页参数
	 * @return IPage<PurIn>   //分页记录
	 */
	@Override 
	public IPage<PurIn> selectList(PurInRequest request, Page<PurIn> page){
	    LambdaQueryWrapper<PurIn> lambdaQueryWrapper = new LambdaQueryWrapper<>();
	    
	    if (null != request.getId()) {
	       lambdaQueryWrapper.eq(PurIn::getId, request.getId());
	      }
		if (StringUtils.hasText(request.getBillNo())) {
			lambdaQueryWrapper.like(PurIn::getBillNo, request.getBillNo());
		}
		if (!VtuzxUtil.isEmpty(request.getInspectBillNo())) {
			lambdaQueryWrapper.like(PurIn::getInspectBillNo, request.getInspectBillNo());
		}
		if (!VtuzxUtil.isEmpty(request.getReceiveBillNo())) {
			lambdaQueryWrapper.like(PurIn::getReceiveBillNo, request.getReceiveBillNo());
		}
		if (!VtuzxUtil.isEmpty(request.getSupplierName())) {
			lambdaQueryWrapper.like(PurIn::getSupplierName, request.getSupplierName());
		}
        if (StringUtils.hasText(request.getInspectUser())) {
			    lambdaQueryWrapper.like(PurIn::getInspectUser, request.getInspectUser());
		    }
//		if (StringUtils.hasText(request.getStockNo())) {
//			lambdaQueryWrapper.like(PurIn::getStockNo, request.getStockNo());
//		}
		if (request.getAuditTime() != null) {
			Date[] fCREATEDATE = request.getAuditTime();
			if (fCREATEDATE.length > 0) {
				// 设置开始时间为当天的零点
				Calendar startCalendar = Calendar.getInstance();
				startCalendar.setTime(fCREATEDATE[0]);
				startCalendar.set(Calendar.HOUR_OF_DAY, 0);
				startCalendar.set(Calendar.MINUTE, 0);
				startCalendar.set(Calendar.SECOND, 0);
				startCalendar.set(Calendar.MILLISECOND, 0);
				Date startDate = startCalendar.getTime();
				lambdaQueryWrapper.ge(PurIn::getAuditTime, startDate);
			}
			if (fCREATEDATE.length == 2) {
				// 设置结束时间为当天的24点
				Calendar endCalendar = Calendar.getInstance();
				endCalendar.setTime(fCREATEDATE[1]);
				endCalendar.set(Calendar.HOUR_OF_DAY, 23);
				endCalendar.set(Calendar.MINUTE, 59);
				endCalendar.set(Calendar.SECOND, 59);
				endCalendar.set(Calendar.MILLISECOND, 999);
				Date endDate = endCalendar.getTime();
				lambdaQueryWrapper.le(PurIn::getAuditTime, endDate);
			}
		}
		if (!VtuzxUtil.isEmpty(request.getStockNo())) {
			String stockNo = request.getStockNo().replace("'", "''"); // 防注入
			lambdaQueryWrapper.inSql(PurIn::getBillNo,
					"SELECT billNo FROM t_pur_in_detail WHERE stockNo = '" + stockNo + "'");
		}
		if (!VtuzxUtil.isEmpty(request.getStatus()) ) {
			lambdaQueryWrapper.eq(PurIn::getStatus,request.getStatus());
		}
		lambdaQueryWrapper.orderByDesc(PurIn::getId);	
		Page<PurIn> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
		return selectPage;
    }
	/**
	 * receive详情
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public Map<String, Object> getPurInDetail(Long user_id,Map<String, Object> map) throws Exception {
		String billNo = map.get("billNo").toString();
		PurIn purinform = purInDao.selectOne(new LambdaQueryWrapper<PurIn>()
				.eq(PurIn::getBillNo,billNo));
		if (null == purinform){
			throw new RuntimeException("单号错误请重试");
		}
		List<PurInDetail> purinList = purInDetailDao.selectList(new LambdaQueryWrapper<PurInDetail>()
				.eq(PurInDetail::getBillNo,billNo));
		//查询是否是地磅称重
		Receive receive = receiveDao.selectOne(new LambdaQueryWrapper<Receive>()
				.eq(Receive::getBillNo, purinform.getReceiveBillNo()));

		List<Map<String, Object>> stockList = selectStcokList(user_id);
		for (PurInDetail purInDetail : purinList){
			String stockNo = purInDetail.getStockNo();
			//金蝶查询当前仓库是否启用仓位
			Boolean aBoolean = stockIsLoc(stockNo,user_id);
			//查询仓库向下的仓位集合
			if (aBoolean){
				List<String> locationList = getlocationList(stockNo);
				purInDetail.setLocationList(locationList);
			}
			purInDetail.setIsLocation(aBoolean);
			purInDetail.setStockList(stockList);
		}
		Boolean isWeight = receive.getIsWeight();
		purinform.setIsWeight(isWeight);

		Map<String,Object> data = new HashMap<>();
		data.put("data",purinform);
		data.put("dataList",purinList);


		return data;
	}

	@Override
	public Boolean createPurIn(Inspect inspect, List<PurInspectDetail> inspectDetailList ,String userName,Long user_id) throws Exception {
		String inspectBillNo = inspect.getBillNo();//检验单号
		String receiveBillNo = inspect.getReceiveBillNo();//收料通知单号

		List<PurInDetail> purInDetailList = new ArrayList<>();
		PurIn purIn = new PurIn();
		String billNo = IXqcConst.createBillNo(BillType.CGRK);
		Double count = 0.0;//外层表的实收数量

		for (PurInspectDetail detail : inspectDetailList){
			PurInDetail purInDetail = new PurInDetail();
			String materialNo = detail.getMaterialNo();
			//金蝶查询当前物料的默认仓库
			Map<String, Object> map = materialStock(user_id,materialNo);
			String stockNumber = VtuzxUtil.getString(map,"stockNo");
			String stockName = VtuzxUtil.getString(map,"stockName");
			if(VtuzxUtil.isEmpty(stockNumber)){
				throw new RuntimeException(String.format("物料:%s,没有默认仓库请维护",materialNo));
			}

			//详情数据
			purInDetail.setBillNo(billNo);
			purInDetail.setMaterialNo(detail.getMaterialNo());
			purInDetail.setMaterialName(detail.getMaterialName());
			purInDetail.setSpecification(detail.getSpecification());
			purInDetail.setUnitName(detail.getUnitName());
			purInDetail.setUnitNo(detail.getUnitNo());
			purInDetail.setFlot(detail.getFlot());
			purInDetail.setMustQty(detail.getInspectQty());//应收数量为检验单的检验数量
			purInDetail.setRealQty(detail.getQualifiedQty());//实收数量为检验单的合个数量
			purInDetail.setUnReceiveQty(detail.getQualifiedQty());//剩余未收数量
			purInDetail.setStatus("save");
			purInDetail.setWeightQty(detail.getInspectQty());//地磅称重数量为检验单的检验数量
			purInDetail.setStockNo(stockNumber);
			purInDetail.setStockName(stockName);
			purInDetail.setLocationNo("998");
			purInDetail.setReveiveId(detail.getReveiveId());
			purInDetail.setReceiveBillNo(detail.getReceiveBillNo());
			purInDetailList.add(purInDetail);
			count += detail.getQualifiedQty();
		}
		purIn.setBillNo(billNo);
		purIn.setSupplierNo(inspect.getSupplierNo());
		purIn.setSupplierName(inspect.getSupplierName());
		purIn.setCreateTime(new DateTime());
		purIn.setCreateUserName(userName);
		purIn.setInspectUser(userName);//质检员
		//仓库填写物料上的默认仓库
//		purIn.setStockNo(stockNumber);
		purIn.setStatus("save");
		purIn.setInspectBillNo(inspectBillNo);
		purIn.setReceiveBillNo(inspect.getReceiveBillNo());//收料通知单号
		purIn.setCount(count);

		boolean inRes = purInService.save(purIn);
		boolean detailRes = purInDetailService.saveOrUpdateBatch(purInDetailList);
		//给库管发送待办通知
		try {
			Map<String,Object> data = new HashMap<>();
			data.put("billNo",billNo);
			yzjService.sendMsgToWare(data,BillType.CGRK.label());
		} catch (Exception e){
			_logger.info(e.getMessage());
		}
		return inRes && detailRes;
	}

	/**
	 * 判断物料是否启用批号
	 * @param materialNo
	 * @return
	 */
	private Map<String,Object> materialStock(Long user_id ,String materialNo) throws Exception{
		VtuzxKingdeeCloudClient client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
		String stockNo = "";
		String stockName = "";
		//查询物料是够启用批号
		List<VtuzxMap> materialQuery = vtuzxKingdeeService.query(client, "BD_MATERIAL", new VtuzxArrayList<>(
						"FStockId.FNumber",//默认仓库
						"FStockId.FName"//默认仓库名称
				),
				String.format("FNumber = '%s'", materialNo), null, 0, 1);
		if (!VtuzxUtil.isEmpty(materialQuery)) {
			stockNo = VtuzxUtil.getString(materialQuery.get(0),"FStockId.FNumber");
			stockName = VtuzxUtil.getString(materialQuery.get(0),"FStockId.FName");
		}
		Map<String,Object> data = new HashMap<>();
		data.put("stockNo",stockNo);
		data.put("stockName",stockName);
		return data;
	}

	@Override
	public Map<String, Object> getPurInList(Map<String, Object> map) {
		int pageIndex = VtuzxUtil.getInt(map,"pageIndex");
		int pageSize = VtuzxUtil.getInt(map,"pageSize");
		String billNo = VtuzxUtil.getString(map,"billNo");//订单号
		//手机端直接获取明细中的数据
		List<PurInDetail> dataList = purInDetailDao.getPurInList(pageSize,pageIndex * pageSize,billNo);
		Map<String,Object> data = new HashMap<>();
		data.put("dataList",dataList);
		return data;
	}

	@Override
	public Boolean auditPurIn(Long user_id,String userName, Map<String, Object> map) throws Exception{
		String billNo = VtuzxUtil.getString(map,"billNo");
		String customAuditDateTime = VtuzxUtil.getString(map,"customAuditDateTime");//用户自定义的入库时间
		_logger.info(String.format("入库单号:%s,自定义入库时间:%s",billNo,customAuditDateTime));
		List<Map<String,Object>> detailList = VtuzxUtil.getObject(map,"dataList");
		PurIn purIn = purInDao.selectOne(new LambdaQueryWrapper<PurIn>().eq(PurIn::getBillNo, billNo));
		List<PurInDetail> purInDetailList = purInDetailDao.selectList(new LambdaQueryWrapper<PurInDetail>()
				.eq(PurInDetail::getBillNo, billNo));

		Map<String,Object> dataMap = new HashMap<>();//key:单号+id.val:仓库，仓位，仓库名称,实收数量
		Map<String,Object> countMap = new HashMap<>();//key:单号+id，val:实收数量
		for (Map<String,Object> data : detailList){
			int id = VtuzxUtil.getInt(data,"id");
			String detailNo = VtuzxUtil.getString(data,"billNo");
			String stockNo = VtuzxUtil.getString(data,"stockNo");
			String stockName = VtuzxUtil.getString(data,"stockName");
			String locationNo = VtuzxUtil.getString(data,"locationNo");
			String flot = VtuzxUtil.getString(data,"flot");
			boolean isLocation = VtuzxUtil.getBoolean(data,"isLocation");
			double realQty = VtuzxUtil.getDouble(data,"realQty");//实收数量
			List<String> locationList = VtuzxUtil.getObject(data,"locationList");

			if (VtuzxUtil.isEmpty(stockNo)){
				throw new RuntimeException("请录入仓库");
			}
			if (isLocation){
				if (VtuzxUtil.isEmpty(locationNo)){
					throw new RuntimeException("请录入仓位");
				}
			} else {
				if (VtuzxUtil.isEmpty(locationNo)){
					locationNo = "";
				}
			}
			if ( isLocation && null != locationList ){
				if (!locationList.contains(locationNo)){
					throw new RuntimeException("仓位不属于当前仓库，请重试");
				}
			}

			Map<String,Object> stockMap =new HashMap<>();
			stockMap.put("stockName",stockName);
			stockMap.put("stockNo",stockNo);
			stockMap.put("locationNo",locationNo);
			stockMap.put("realQty",realQty);
			stockMap.put("isLocation",isLocation);
			stockMap.put("flot",flot);
			dataMap.put(detailNo + id,stockMap);
		}
		//数据库添加仓位信息,批号
		for (PurInDetail detail : purInDetailList){
			Double mustQty = detail.getMustQty();//应收数量
			Double unReceiveQty = detail.getUnReceiveQty();//剩余未收数量
			String billNo1 = detail.getBillNo();
			Long id = detail.getId();
			Map<String,Object> stockMap = VtuzxUtil.getObject(dataMap,billNo1 + id);
			String locationNo = VtuzxUtil.getString(stockMap,"locationNo");
			String stockNo = VtuzxUtil.getString(stockMap,"stockNo");
			String stockName = VtuzxUtil.getString(stockMap,"stockName");
			String flot = VtuzxUtil.getString(stockMap,"flot");
			double realQty = VtuzxUtil.getDouble(stockMap,"realQty");
			Boolean isLocation = VtuzxUtil.getBoolean(stockMap,"isLocation");
			detail.setLocationNo(locationNo);
			detail.setStockName(stockName);
			detail.setStockNo(stockNo);
			detail.setRealQty(realQty);
			detail.setIsLocation(isLocation);
			detail.setFlot(flot);
		}
		purInDetailService.saveOrUpdateBatch(purInDetailList);

		//修改外层表单据为审核状态，添加审核时间和审核人
		purIn.setAuditTime(new DateTime());
		purIn.setAuditUserName(userName);
		purIn.setStatus("audit");
		try {
			syncKingdeeOrderService.syncPurInOrder(user_id,userName,purIn,purInDetailList,customAuditDateTime);
		} catch (Exception e){
			throw new RuntimeException(e.getMessage());
		}

		boolean res = purInService.saveOrUpdate(purIn);



		return res;
	}

	@Override
	public Map<String, Object> getPurInDetailPhone(Long user_id, Map<String, Object> map) throws Exception {
		Long detailId = VtuzxUtil.getLong(map,"detailId");

		PurInDetail purInDetail = purInDetailDao.selectById(detailId);
		List<Map<String, Object>> stockList = selectStcokList(user_id);
		String stockNo = purInDetail.getStockNo();
		//金蝶查询当前仓库是否启用仓位
		Boolean aBoolean = stockIsLoc(stockNo,user_id);
		//查询仓库向下的仓位集合
		if (aBoolean){
			List<String> locationList = getlocationList(stockNo);
			purInDetail.setLocationList(locationList);
		}
		purInDetail.setIsLocation(aBoolean);
		purInDetail.setStockList(stockList);
		//实收数量默认等于剩余未收数量
		purInDetail.setRealQty(purInDetail.getUnReceiveQty());

		Map<String,Object> data = new HashMap<>();
		data.put("data",purInDetail);

		return data;
	}

	/**
	 * 审核采购入库单pda
	 * @param user_id
	 * @param userName
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public Boolean auditPurInPda(Long user_id, String userName, Map<String, Object> map) throws Exception {
		Map<String,Object> header = VtuzxUtil.getObject(map,"header");
		//每次审核后都传金蝶采购入库单，并且修改剩余未收数量 = 剩余未收 - 实收
		Long detailId = VtuzxUtil.getLong(header,"id");
		double realQty = VtuzxUtil.getDouble(header,"realQty");//本次入库的实收数量
		PurInDetail purInDetail = purInDetailDao.selectById(detailId);
		purInDetail.setUnReceiveQty(purInDetail.getUnReceiveQty() - realQty);
		//如果剩余未收等于0说明这个明细完事了
		if (purInDetail.getUnReceiveQty()  == 0){
			purInDetail.setStatus("audit");
		}

		//传金蝶采购入库单
		try {
			syncKingdeeOrderService.syncPurInOrderByPda(user_id,userName,header);
		} catch (Exception e){
//			_logger.info(e.getMessage());
			throw new RuntimeException(e.getMessage());
		}
		boolean b = purInDetailService.updateById(purInDetail);
		return b;
	}

	/**
	 * 查询仓库集合(只查询当前用户所绑定的仓库)
	 * @return
	 */
	private List<Map<String,Object>> selectStcokList(Long user_id) throws Exception{
		SysAdmin sysAdmin = adminService.getById(user_id);
		if (VtuzxUtil.isEmpty(sysAdmin.getStockNoList())){
			throw new RuntimeException("当前用户没有关联仓库,请维护");
		}
		String stockNoList = sysAdmin.getStockNoList();//仓库集合
		List<String> stockNos = Arrays.asList(stockNoList.split(","));
		String materialNoCond = org.springframework.util.StringUtils.collectionToDelimitedString(stockNos, ",", "'", "'");
		VtuzxKingdeeCloudClient client = null;
		try {
			client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
		} catch (Exception e){
			throw new RuntimeException("金蝶账号密码错误，请维护");
		}
		List<Map<String,Object>> dataList = new ArrayList<>();
		String cond = String.format("FNumber in (%s)",materialNoCond);
		List<VtuzxMap> materialQuery = vtuzxKingdeeService.query(client, "BD_STOCK", new VtuzxArrayList<>(
						"FName",
						"FNumber"
				),
				cond, null, 0, 0);
		if (!VtuzxUtil.isEmpty(materialQuery)) {
			for (VtuzxMap data : materialQuery){
				Map<String,Object> map =new HashMap<>();
				String fname = VtuzxUtil.getString(data,"FName");
				String FNumber = VtuzxUtil.getString(data,"FNumber");
				map.put("value",FNumber);
				map.put("text",fname);
				dataList.add(map);
			}
		}
		return dataList;
	}
	/**
	 * 判断仓库是否启用仓位
	 * @param stockNo
	 * @return
	 */
	private Boolean stockIsLoc(String stockNo,Long user_id) throws Exception{
		VtuzxKingdeeCloudClient client = null;
		try {
			client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
		} catch (Exception e){
			throw new RuntimeException("金蝶账号密码错误,请维护");
		}
		Boolean FIsOpenLocation = false;
		//查询物料是够启用批号
		List<VtuzxMap> materialQuery = vtuzxKingdeeService.query(client, "BD_STOCK", new VtuzxArrayList<>(
						"FIsOpenLocation"//是否启用仓位
				),
				String.format("FNumber = '%s'", stockNo), null, 0, 1);
		if (!VtuzxUtil.isEmpty(materialQuery)) {
			FIsOpenLocation = VtuzxUtil.getBoolean(materialQuery.get(0),"FIsOpenLocation");
		}
		return FIsOpenLocation;
	}

	/**
	 * 查询仓库向下的仓位信息
	 * @param stockNo
	 * @return
	 */
	private List<String> getlocationList(String stockNo) throws Exception{
		VtuzxKingdeeCloudClient client = vtuzxKingdeeService.loginKingdee();
		List<String> dataList = new ArrayList<>();
		//查询物料是够启用批号
		List<VtuzxMap> materialQuery = vtuzxKingdeeService.query(client, "BD_STOCK", new VtuzxArrayList<>(
						"FFlexEntryId.fnumber",//仓位编码
						"FFlexEntryName"//仓位名称
				),
				String.format("FNumber = '%s'", stockNo), null, 0, 0);
		if (!VtuzxUtil.isEmpty(materialQuery)) {
			for (Map<String,Object> data : materialQuery){
				String locationNo = VtuzxUtil.getString(data,"FFlexEntryId.fnumber");
//				String locationName = VtuzxUtil.getString(data,"FFlexEntryName");
//				Map<String,Object> locMap = new HashMap<>();
//				locMap.put("value",locationNo);
//				locMap.put("text",locationName);
				dataList.add(locationNo);
			}

		}
		return dataList;
	}

}